package org.campuscontent.ui;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import java.util.Vector;

import org.campuscontent.ui.layout.AlignmentLayout.Alignment;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.GraphConstants;

public class UIUtils
{
    public static Point2D[] getDefaultControlPoints( DefaultGraphCell source, DefaultGraphCell target, DefaultEdge edge )
    {
        Point2D[] result = new Point2D[ 3 ];
        
        AttributeMap Smap   = source.getAttributes(); 
        AttributeMap Tmap   = target.getAttributes();
        Rectangle2D Sbounds = GraphConstants.getBounds( Smap );
        Rectangle2D Tbounds = GraphConstants.getBounds( Tmap );
        
        double mX = Math.min( Sbounds.getCenterX(), Tbounds.getCenterX() );
        double mY = Math.min( Sbounds.getCenterY(), Tbounds.getCenterY() );
        
        double offSetX = Math.abs( Sbounds.getCenterX() - Tbounds.getCenterX() ) / 2;
        double offSetY = Math.abs( Sbounds.getCenterY() - Tbounds.getCenterY() ) / 2;
        
        result[ 0 ] = new Point2D.Double( Sbounds.getCenterX(), Sbounds.getCenterY() );
        result[ 1 ] = new Point2D.Double( mX + offSetX, mY + offSetY );
        result[ 2 ] = new Point2D.Double( Tbounds.getCenterX(), Tbounds.getCenterY() );
                
        return result;
    }
    
    public static Point2D[] getDefaultControlPointsForLayout( Rectangle2D scBounds, Rectangle2D tgBounds, DefaultEdge edge, Alignment align )
    {
        Point2D[] result = new Point2D[ 3 ];
        
        double mX = Math.min( scBounds.getCenterX(), tgBounds.getCenterX() );
        double mY = Math.min( scBounds.getCenterY(), tgBounds.getCenterY() );
        
        double offSetX = Math.abs( scBounds.getCenterX() - tgBounds.getCenterX() ) / 2;
        double offSetY = Math.abs( scBounds.getCenterY() - tgBounds.getCenterY() ) / 2;
        
        double offSetArc    = 0;
        
        result[ 0 ] = new Point2D.Double( scBounds.getCenterX(), scBounds.getCenterY() );
        
        if ( align == Alignment.VERTICAL )
        {
            offSetArc = offSetY * 0.3;
            result[ 1 ] = new Point2D.Double( mX + offSetX + offSetArc, mY + offSetY );
        }
        else if ( align == Alignment.HORIZONTAL )
        {
            offSetArc = offSetX * 0.3;
            result[ 1 ] = new Point2D.Double( mX + offSetX, mY + offSetY + offSetArc );
        }
        else if ( align == Alignment.DIAGONAL )
        {
            offSetX *= 2;
            offSetY *= 2;
            
            offSetX = offSetX * 3 / 4;
            offSetY = offSetX * 1 / 4;
            
            result[ 1 ] = new Point2D.Double( mX + offSetX, mY + offSetY );
        }
        else
        {
            result[ 1 ] = new Point2D.Double( mX + offSetX, mY + offSetY );
        }
        
        result[ 2 ] = new Point2D.Double( tgBounds.getCenterX(), tgBounds.getCenterY() );
        
        return result;
    }
    
    public static Object[] getFullCellsOfCurrentSelection( AutomataGraph graph )
    {
        if ( graph != null && !graph.isSelectionEmpty() )
        {
            Object[] cells = graph.getSelectionCells();
            cells = graph.getDescendants( cells );

            Vector<Object> extra = new Vector<Object> ( 5, 3 );
            for ( Object o : cells )
            {
                if ( o instanceof DefaultPort )
                {
                    DefaultPort dp = (DefaultPort)o;
                    Iterator edges = dp.edges();
                    while ( edges.hasNext() )
                    {
                        Object oe = edges.next();
                        extra.add( oe );
                    }
                }
                
                extra.add( o );
            }
            
            return extra.toArray( new Object[]{} );
        }

        return null;
    }
}
